<?php
// +----------------------------------------------------------------------
// | yylAdmin 前后分离，简单轻量，免费开源，开箱即用，极简后台管理系统
// +----------------------------------------------------------------------
// | Copyright https://gitee.com/skyselang All rights reserved
// +----------------------------------------------------------------------
// | Gitee: https://gitee.com/skyselang/yylAdmin
// +----------------------------------------------------------------------

// 文件管理
namespace app\service;

use app\api\model\FileSystem as FileModel;

class FileService
{
    /**
     * 文件列表
     *
     * @param array  $where 条件
     * @param int    $page  页数
     * @param int    $limit 数量
     * @param array  $order 排序
     * @param string $field 字段
     * 
     * @return array 
     */
    public static function list($where = [], $page = 1, $limit = 10, $order = [], $field = '')
    {
        $model = new FileModel();
        $pk = 'file_id';


        if (empty($field)) {
            $field = 'file_id,group_id,storage,domain,file_md5,file_hash,file_type,file_name,file_path,file_size,file_ext,sort,is_disable';
        } else {
            $field = str_merge($field, 'file_id,storage,domain,file_md5,file_hash,file_path,file_ext');
        }

        if (empty($order)) {
            $order = ['update_time' => 'desc', 'sort' => 'desc', $pk => 'desc'];
        }

        $count = $model->where($where)->count($pk);

        $pages = $count ? ceil($count / $limit) : 0;

        $list = $model->field($field)->where($where)->page($page)->limit($limit)->order($order)->select()->toArray();

        foreach ($list as $k => $v) {
            $list[$k]['file_url'] = self::fileUrl($v);
            if (isset($v['file_size'])) {
                $list[$k]['file_size'] = self::fileSize($v['file_size']);
            }
        }

        $ids = array_column($list, $pk);

        return compact('count', 'pages', 'page', 'limit', 'list', 'ids');
    }

    /**
     * 文件信息
     *
     * @param int $id 文件id
     * 
     * @return array
     */
    public static function info($id)
    {
        if (empty($id)) {
            return [];
        }

        $model = new FileModel();
        $info = $model->find($id);
        if (empty($info)) {
            return [];
        } else {
            $info = $info->toArray();
            if ($info['is_disable']) {
                $info['file_url'] = '';
            } else {
                $info['file_url'] = self::fileUrl($info);
            }
            $info['file_size'] = self::fileSize($info['file_size']);

        }

        return $info;
    }

    /**
     * 文件添加
     *
     * @param array $param 文件信息
     * 
     * @return array|Exception
     */
    public static function add($param)
    {
        $file = request()->file('file');
        if(!$file){
            return false;
        }

        $file_id = isset($param['file_id']) ? $param['file_id'] : 0;
        $time = time();


        $fileinfo = $file->move(ROOT_PATH . 'disk' . DS . 'uploads');


        $file_ext  = $fileinfo->getExtension();
        $file_type = self::getFileType($file_ext);
        $file_size = $fileinfo->getSize();
        $file_md5  = $fileinfo->hash('md5');
        $file_hash = $fileinfo->hash('sha1');

        $param['file_md5']  = $file_md5;
        $param['file_hash'] = $file_hash;
        $param['file_path'] = DS . 'disk' . DS . 'uploads' . DS . $fileinfo->getSaveName();
        $param['file_ext']  = $file_ext;
        $param['file_size'] = $file_size;
        $param['file_type'] = $file_type;
        if (empty($param['file_name'])) {
            // $param['file_name'] = mb_substr($fileinfo->getFilename(), 0, - (mb_strlen($param['file_ext']) + 1));
            $param['file_name'] = mb_substr($file->getInfo()['name'], 0, - (mb_strlen($param['file_ext']) + 1));
        }

        // 对象存储
        $param = StorageService::upload($param);

        $model = new FileModel();
        $pk = 'file_id';

        // $file_exist = $model->field($pk)->where('file_hash', $file_hash)->find();
        $file_exist = $model->field($pk)->where('file_id', $file_id)->find();
        if ($file_exist) {
            $file_exist = $file_exist->toArray();
            $file_update[$pk]          = $file_exist[$pk];
            $file_update['storage']    = $param['storage'];
            $file_update['domain']     = $param['domain'];
            $file_update['is_disable'] = 0;
            $file_update['is_delete']  = 0;
            self::edit($file_update);
            $id = $file_exist[$pk];
        } else {
            $param['create_time'] = $time;
            $param['update_time'] = $time;
            $id = $model->strict(false)->insertGetId($param);
            if (empty($id)) {
                return false;
            }
        }

        $info = self::info($id);

        return $info;
    }

    /**
     * 文件修改
     *
     * @param array $param 文件信息
     * 
     * @return array|Exception
     */
    public static function edit($param)
    {
        $model = new FileModel();
        $pk = 'file_id';

        $id = $param[$pk];
        unset($param[$pk]);

        $param['update_time'] = datetime();

        $res = $model->where($pk, $id)->update($param);
        if (empty($res)) {
            exception();
        }


        $param[$pk] = $id;

        return $param;
    }

    /**
     * 文件删除
     *
     * @param array $ids       文件id
     * @param int   $is_delete 是否删除
     * 
     * @return array|Exception
     */
    public static function dele($ids, $is_delete = 1)
    {
        $model = new FileModel();
        $pk = 'file_id';

        $update['is_delete']   = $is_delete;
        $update['delete_time'] = datetime();

        $res = $model->where($pk, 'in', $ids)->update($update);
        if (empty($res)) {
            exception();
        }


        $update['ids'] = $ids;

        return $update;
    }

    /**
     * 文件修改分组
     *
     * @param array $ids      文件id
     * @param int   $group_id 分组id
     * 
     * @return array|Exception
     */
    public static function editgroup($ids, $group_id = 0)
    {
        $model = new FileModel();
        $pk = 'file_id';

        $update['group_id']    = $group_id;
        $update['update_time'] = datetime();

        $res = $model->where($pk, 'in', $ids)->update($update);
        if (empty($res)) {
            exception();
        }


        $update['ids'] = $ids;

        return $update;
    }

    /**
     * 文件修改类型
     *
     * @param array  $ids       文件id
     * @param string $file_type 文件类型
     * 
     * @return array|Exception
     */
    public static function edittype($ids, $file_type = 'image')
    {
        $model = new FileModel();
        $pk = 'file_id';

        $update['file_type']   = $file_type;
        $update['update_time'] = datetime();

        $res = $model->where($pk, 'in', $ids)->update($update);
        if (empty($res)) {
            exception();
        }


        $update['ids'] = $ids;

        return $update;
    }

    /**
     * 文件修改域名
     *
     * @param array  $ids    文件id
     * @param string $domain 文件域名
     * 
     * @return array|Exception
     */
    public static function editdomain($ids, $domain = '')
    {
        $model = new FileModel();
        $pk = 'file_id';

        $update['domain']      = $domain;
        $update['update_time'] = datetime();

        $res = $model->where($pk, 'in', $ids)->update($update);
        if (empty($res)) {
            exception();
        }


        $update['ids'] = $ids;

        return $update;
    }

    /**
     * 文件是否禁用
     *
     * @param array $ids        文件id
     * @param int   $is_disable 是否禁用
     * 
     * @return array|Exception
     */
    public static function disable($ids, $is_disable = 0)
    {
        $model = new FileModel();
        $pk = 'file_id';

        $update['is_disable']  = $is_disable;
        $update['update_time'] = datetime();

        $res = $model->where($pk, 'in', $ids)->update($update);
        if (empty($res)) {
            exception();
        }


        $update['ids'] = $ids;

        return $update;
    }


    /**
     * 文件回收站恢复
     * 
     * @param array $ids 文件id
     * 
     * @return array|Exception
     */
    public static function recoverReco($ids)
    {
        $model = new FileModel();
        $pk = 'file_id';

        $update['is_delete']   = 0;
        $update['update_time'] = datetime();

        $res = $model->where($pk, 'in', $ids)->update($update);
        if (empty($res)) {
            exception();
        }


        $update['ids'] = $ids;

        return $update;
    }

    /**
     * 文件回收站删除
     * 
     * @param array $ids 文件id
     * 
     * @return array|Exception
     */
    public static function recoverDele($ids)
    {
        $model = new FileModel();
        $pk = 'file_id';

        $file = $model->field($pk . ',file_path')->where($pk, 'in', $ids)->select();

        $res = $model->where($pk, 'in', $ids)->delete();
        if (empty($res)) {
            exception();
        }

        $del = [];
        foreach ($file as $v) {
            $del[] = @unlink($v['file_path']);
        }

        $update['ids'] = $ids;
        $update['del'] = $del;

        return $update;
    }

    /**
     * 文件链接
     *
     * @param mixed $file 文件id、信息
     *
     * @return string
     */
    public static function fileUrl($file)
    {
        if (is_numeric($file)) {
            $file = self::info($file);
        }

        $file_url = '';
        if ($file) {
            if (!$file['is_disable']) {
                if ($file['storage'] == 'local') {
                    $file_url = file_url($file['file_path']);
                } else {
                    $file_url = $file['domain'] . '/' . $file['file_hash'] . '.' . $file['file_ext'];
                }
            }
        }

        return $file_url;
    }

    /**
     * 文件数组
     *
     * @param string $ids 文件id，逗号,隔开
     *
     * @return array
     */
    public static function fileArray($ids)
    {
        $model = new FileModel();
        $pk = 'file_id';

        $field = $pk . ',storage,file_type,domain,file_name,file_hash,file_ext,file_path,file_size,is_disable';
        $where[] = [$pk, 'in', $ids];
        $where[] = ['is_disable', '=', 0];
        $file = $model->field($field)->where($where)->select()->toArray();
        foreach ($file as $k => $v) {
            $file[$k]['file_url']  = self::fileUrl($v);
            $file[$k]['file_size'] = self::fileSize($v['file_size']);
        }

        return $file;
    }

    /**
     * 文件统计
     *   
     * @return array
     */
    public static function statistics()
    {
        $key = 'count';
        $model = new FileModel();
        $pk = 'file_id';

        $file_types = self::fileType();
        $file_field = 'file_type,count(file_type) as count';
        $file_count = $model->field($file_field)->where('is_delete', 0)->group('file_type')->select()->toArray();
        foreach ($file_types as $k => $v) {
            $temp = [];
            $temp['name']  = $v;
            $temp['value'] = 0;
            foreach ($file_count as $vfc) {
                if ($k == $vfc['file_type']) {
                    $temp['value'] = $vfc['count'];
                }
            }
            $data['data'][] = $temp;
        }
        $data['count'] = $model->where('is_delete', 0)->count($pk);


        return $data;
    }












    /**
     * 文件类型数组
     *
     * @return array
     */
    public static function fileType()
    {
        $filetype = [
            'image' => '图片',
            'video' => '视频',
            'audio' => '音频',
            'word'  => '文档',
            'other' => '其它'
        ];

        return $filetype;
    }

    /**
     * 文件储存方式
     *
     * @return array
     */
    public static function storage()
    {
        $storage = [
            'local'   => '本地(服务器)',
            'aliyun'  => '阿里云OSS',
        ];

        return $storage;
    }

    /**
     * 文件大小格式化
     *
     * @param int $file_size 文件大小（byte(B)字节）
     *
     * @return string
     */
    public static function fileSize($file_size = 0)
    {
        $p = 0;
        $format = 'B';
        if ($file_size > 0 && $file_size < 1024) {
            $p = 0;
            return number_format($file_size) . ' ' . $format;
        }
        if ($file_size >= 1024 && $file_size < pow(1024, 2)) {
            $p = 1;
            $format = 'KB';
        }
        if ($file_size >= pow(1024, 2) && $file_size < pow(1024, 3)) {
            $p = 2;
            $format = 'MB';
        }
        if ($file_size >= pow(1024, 3) && $file_size < pow(1024, 4)) {
            $p = 3;
            $format = 'GB';
        }
        if ($file_size >= pow(1024, 4) && $file_size < pow(1024, 5)) {
            $p = 3;
            $format = 'TB';
        }

        $file_size /= pow(1024, $p);

        return number_format($file_size, 2) . ' ' . $format;
    }

    /**
     * 文件类型获取
     *
     * @param string $file_ext 文件后缀
     *
     * @return string image图片，video视频，audio音频，word文档，other其它
     */
    public static function getFileType($file_ext = '')
    {
        if ($file_ext) {
            $file_ext = strtolower($file_ext);
        }

        $image_ext = [
            'jpg', 'png', 'jpeg', 'gif', 'bmp', 'webp', 'ico', 'svg', 'tif', 'pcx', 'tga', 'exif',
            'psd', 'cdr', 'pcd', 'dxf', 'ufo', 'eps', 'ai', 'raw', 'wmf',  'avif', 'apng', 'xbm', 'fpx'
        ];
        $video_ext = [
            'mp4', 'avi', 'mkv', 'flv', 'rm', 'rmvb', 'webm', '3gp', 'mpeg', 'mpg', 'dat', 'asx', 'wmv',
            'mov', 'm4a', 'ogm', 'vob', 'ogv'
        ];
        $audio_ext = [
            'mp3', 'aac', 'wma', 'wav', 'ape', 'flac', 'ogg', 'adt', 'adts', 'cda', 'cd', 'wave',
            'aiff', 'midi', 'ra', 'rmx', 'vqf', 'amr'
        ];
        $word_ext = [
            'doc', 'docx', 'docm', 'dotx', 'dotm', 'txt',
            'xls', 'xlsx', 'xlsm', 'xltx', 'xltm', 'xlsb', 'xlam', 'csv',
            'ppt', 'pptx', 'potx', 'potm', 'ppam', 'ppsx', 'ppsm', 'sldx', 'sldm', 'thmx'
        ];

        if (in_array($file_ext, $image_ext)) {
            return 'image';
        } elseif (in_array($file_ext, $video_ext)) {
            return 'video';
        } elseif (in_array($file_ext, $audio_ext)) {
            return 'audio';
        } elseif (in_array($file_ext, $word_ext)) {
            return 'word';
        } else {
            return 'other';
        }
    }
}
